package com.example.jpa_h2_querydsl.service;

import com.example.jpa_h2_querydsl.entity.H2User;
import com.example.jpa_h2_querydsl.entity.QH2User;
import com.example.jpa_h2_querydsl.repository.H2UserRepository;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.jpa.impl.JPAQueryFactory;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.criteria.CriteriaQuery;
import jakarta.persistence.criteria.Root;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.ExampleMatcher;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class H2UserService {
    @Autowired
    H2UserRepository h2UserRepository;

    // 注入 EntityManager
    @PersistenceContext
    EntityManager entityManager;
    public void findUser(){
        H2User h2User = new H2User();
        h2User.setUsername("username");
        Example<H2User> example = Example.of(h2User,ExampleMatcher.matchingAny());
        List<H2User> all = h2UserRepository.findAll(example, Sort.unsorted());
        h2UserRepository.findByUsername("user");

        h2UserRepository.findOne("tom");
    }

    public void findCriteria(){
        CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
        CriteriaQuery<H2User> query = criteriaBuilder.createQuery(H2User.class);
        Root<H2User> from = query.from(H2User.class);
        query.where(criteriaBuilder.notEqual(from.get("username"),"tom"));
        entityManager.createQuery(query).getResultList();

    }
    public void findAllUser(){
        Specification<H2User> spec = Specification.allOf(H2UserSpecifications.hasUser());

        List<H2User> all = h2UserRepository.findAll(spec);

    }

    public void findAllUserQueryDsl(){
        //1, 通过 EntityManager 创建 JPAQueryFactory 实例
        var query = new JPAQueryFactory(entityManager);
        query.selectFrom(QH2User.h2User).fetchOne();

        //2, 通过extends QuerydslPredicateExecutor 接口
        QH2User h2User = QH2User.h2User;
        BooleanBuilder booleanBuilder = new BooleanBuilder();
        booleanBuilder.and(h2User.username.isNotNull());
        h2UserRepository.findAll(booleanBuilder);
    }


    public static class H2UserSpecifications {
        public static Specification<H2User> hasUser() {
            return ((root, query, criteriaBuilder) -> criteriaBuilder.isNotNull(root.<String>get("username")));
        }
    }
}
